﻿using System;
using System.Collections.Generic;
using System.Text;
using NHibernate;

namespace NCommet.Modules.Dao
{
    /// <summary>
    /// It allows for more than one <see cref="NHibernate.IInterceptor"/> implementations to be used with NHibernate. But <see cref="NCommet.Modules.Dao.CompositeInterceptor"/> should be used as the sole <see cref="NHibernate.IInterceptor"/> implementation for NHibernate.
    /// </summary>
    public class CompositeInterceptor : IInterceptor
    {
        private List<IInterceptor> interceptors = new List<IInterceptor>();

        public void AddInterceptor(IInterceptor interceptor)
        {
            interceptors.Add(interceptor);
        }

        public void RemoveInterceptor(IInterceptor interceptor)
        {
            interceptors.Remove(interceptor);
        }

        #region IInterceptor Members
        public void AfterTransactionBegin(ITransaction tx)
        {
            foreach (IInterceptor interceptor in interceptors)
                interceptor.AfterTransactionBegin(tx);
        }

        public void AfterTransactionCompletion(ITransaction tx)
        {
            foreach (IInterceptor interceptor in interceptors)
                interceptor.AfterTransactionCompletion(tx);
        }

        public void BeforeTransactionCompletion(ITransaction tx)
        {
            foreach (IInterceptor interceptor in interceptors)
                interceptor.BeforeTransactionCompletion(tx);
        }

        public void SetSession(ISession session)
        {
            foreach (IInterceptor interceptor in interceptors)
                interceptor.SetSession(session);
        }

        public int[] FindDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, NHibernate.Type.IType[] types)
        {
            int[] result = null;
            foreach (IInterceptor interceptor in interceptors)
            {
                result = interceptor.FindDirty(entity, id, currentState, previousState, propertyNames, types);
                if (result != null)
                    break;
            }
            return result;
        }

        public object Instantiate(Type type, object id)
        {
            object result = null;
            foreach (IInterceptor interceptor in interceptors)
            {
                result = interceptor.Instantiate(type, id);
                if (result != null)
                    break;
            }
            return result;
        }

        public object IsUnsaved(object entity)
        {
            object result = null;
            foreach (IInterceptor interceptor in interceptors)
            {
                result = interceptor.IsUnsaved(entity);
                if (result != null)
                    break;
            }
            return result;
        }

        public void OnDelete(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
        {
            foreach (IInterceptor interceptor in interceptors)
                interceptor.OnDelete(entity, id, state, propertyNames, types);
        }

        public bool OnFlushDirty(object entity, object id, object[] currentState, object[] previousState, string[] propertyNames, NHibernate.Type.IType[] types)
        {
            bool result = false;
            foreach (IInterceptor interceptor in interceptors)
            {
                result = interceptor.OnFlushDirty(entity, id, currentState, previousState, propertyNames, types);
                if (result != false)
                    break;
            }
            return result;
        }

        public bool OnLoad(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
        {
            bool result = false;
            foreach (IInterceptor interceptor in interceptors)
            {
                result = interceptor.OnLoad(entity, id, state, propertyNames, types);
                if (result != false)
                    break;
            }
            return result;
        }

        public bool OnSave(object entity, object id, object[] state, string[] propertyNames, NHibernate.Type.IType[] types)
        {
            bool result = false;
            foreach (IInterceptor interceptor in interceptors)
            {
                result = interceptor.OnSave(entity, id, state, propertyNames, types);
                if (result != false)
                    break;
            }
            return result;
        }

        public void PostFlush(System.Collections.ICollection entities)
        {
            foreach (IInterceptor interceptor in interceptors)
                interceptor.PostFlush(entities);
        }

        public void PreFlush(System.Collections.ICollection entities)
        {
            foreach (IInterceptor interceptor in interceptors)            
                interceptor.PreFlush(entities);            
        }

        #endregion
    }
}
